import os
import time

from django.db import models

from model.Constants import PointImagePath, PointIconPath, PointDefaultIconPath, PointDefaultImagePath, DefaultPng


class Point(models.Model):
    """ Map marker points """

    class Meta:
        db_table = 'point'
        verbose_name = 'point'
        verbose_name_plural = verbose_name

    class Type(models.IntegerChoices):
        """ The type of the marker point  """
        person = 1
        share = 2

    class Status(models.IntegerChoices):
        """ The apply status of the share point  """
        normal = 1
        applying = 2
        apply_approve = 3
        apply_not_approve = 4

    pid = models.AutoField(
        verbose_name='The unique ID of the marked point',
        primary_key=True
    )
    name = models.CharField(
        verbose_name='The name of the marked point',
        max_length=20, null=False
    )
    detail = models.CharField(
        verbose_name='The detail description of the marked point',
        max_length=200, default=None, null=True
    )
    longitude = models.DecimalField(
        verbose_name='The longitude of the marked point',
        max_digits=12, decimal_places=8, default=None, null=True,
    )
    latitude = models.DecimalField(
        verbose_name='The latitude of the marked point',
        max_digits=12, decimal_places=8, default=None, null=True
    )
    direction = models.CharField(
        verbose_name='The direction of the marked point',
        max_length=200, default=None, null=True
    )
    uploader = models.ForeignKey(
        verbose_name='The uploader of the marked point',
        to='user', null=False, on_delete=models.CASCADE
    )
    uploadTime = models.DateTimeField(
        verbose_name='The upload time of the marked point',
        null=False, auto_now_add=True
    )
    modifyTime = models.DateTimeField(
        verbose_name='The latest modify time of the marked point',
        null=True, auto_now=True
    )
    type = models.IntegerField(
        verbose_name='The type of the marker point',
        choices=Type.choices, default=Type.person, null=False
    )
    status = models.IntegerField(
        verbose_name='The status of the marker point',
        choices=Status.choices, default=Status.normal, null=False
    )
    photo = models.ImageField(
        verbose_name='The photo of the marker point',
        upload_to=PointImagePath, default=PointDefaultImagePath, null=True,
    )
    icon = models.ImageField(
        verbose_name='The icon of the marker point',
        upload_to=PointIconPath, default=PointDefaultIconPath, null=True,
    )

    def info(self):
        return {
            'pid': self.pid,
            'name': self.name,
            'detail': self.detail,
            'longitude': self.longitude,
            'latitude': self.latitude,
            'direction': self.direction,
            'uploader': self.uploader.uid,
            'uploadTime': self.uploadTime,
            'modifyTime': self.modifyTime,
            'type': self.type,
            'status': self.status,
            'photo': self.photo.name and os.path.basename(self.photo.name),
            'icon': self.icon.name and os.path.basename(self.icon.name),
        }

    def set_type(self, type):
        self.type = type
        self.save()

    def set_status(self, status):
        self.status = status
        self.save()

    def setIcon(self, file):
        if self.icon and os.path.basename(self.photo.name) != DefaultPng:
            self.icon.delete()

        from server.utils import Md5
        name = Md5(file.name, salt=time.time())
        format = file.content_type[-3:]
        file.name = f"{name}.{format}"
        self.icon = file
        self.save()
        return file.name

    def setPhoto(self, file):
        if self.photo and os.path.basename(self.photo.name) != DefaultPng:
            self.photo.delete()

        from server.utils import Md5
        name = Md5(file.name, salt=time.time())
        format = file.content_type[-3:]
        file.name = f"{name}.{format}"
        self.photo = file
        self.save()
        return file.name
